home *** CD-ROM | disk | FTP | other *** search
- /*
- * TWindows.c
- *
- * C source of an extended Window Manager that supports tool windows;
- * these are windows that always float on top, for palettes and tools.
- *
- * Written in MPW C 2.0
- *
- * Copyright Thomas Fruin 1988
- * All rights reserved.
- *
- * fruin@hlerul5.BITNET University of Leiden
- * thomas@uvabick.UUCP University of Amsterdam
- * dibs@well.UUCP
- * hol0066.AppleLink
- * 2:508/15.FidoNet The Netherlands
- */
-
-
- /*
- * T O O L B O X I N C L U D E S
- *
- * Header files for the Toolbox data types and functions
- * used in this source file.
- */
-
- #include <Types.h>
- #include <Memory.h>
- #include <Quickdraw.h>
- #include <Events.h>
- #include <Windows.h>
- #include <ToolUtils.h>
- #include <OSUtils.h>
- #include <Resources.h>
-
-
- /*
- * T O O L B O X D E F I N I T I O N S
- *
- * Definitions of low memory global variables:
- *
- * o GrayRgn is a handle to the current desktop region, a region
- * encompassing the complete desktop space ( possibly spread
- * out over more than one screen). Only needed on the old 64K
- * ROM Macintosh and the Mac XL, since there is the new func-
- * tion GetGrayRgn that also returns this handle.
- * o WindowList is a pointer to the very first window. By tra-
- * versing the nextWindow fields in each WindowRecord, you can
- * access each window in turn. This global is more than just
- * FrontWindow(), because the function only returns the first
- * _visible_ window.
- */
-
- #define GrayRgn (*(RgnHandle *)0x9EE)
- #define WindowList (*(WindowPeek *)0x9D6)
-
-
- /*
- * D E F I N I T I O N S
- *
- * The constants used in this source file.
- */
-
- /* Defines LONGINT, INTEGER, the windowKind constants
- and the externally callable TWindow Manager functions. */
-
- #include <TWindows.h>
-
- /* Result codes describing window positions, as
- returned by the function GetWPosition. */
-
- #define alone 0 /* no other windows visible */
- #define beforeDialog 1 /* it is before the frontmost */
- /* window, which is a dialog */
- #define beforeSystem 2 /* it is before the frontmost */
- /* window, which is a DA */
- #define beforeTool 3 /* it is before the frontmost */
- /* window, which is a tool */
- #define beforeDocument 4 /* it is before the frontmost */
- /* window, which is a document */
- #define behindFrontSystem 5 /* it is behind the frontmost */
- /* window, which is a DA */
- #define betweenTools 6 /* it is among the tool windows */
- #define behindTools 7 /* it is behind all tool windows, */
- /* but before document windows */
- #define behindSystem 8 /* it is behind all tool windows, */
- /* and behind a DA */
- #define betweenDocuments 9 /* it is behind the frontmost */
- /* document window */
-
- /* Miscellaneous */
-
- #define deactivFlag 0 /* modifiers for deactivate event */
- #define noDrag -32768 /* possible result of DragGrayRgn */
- #define invisible false /* when calling NewWindow */
- #define curVersion 1 /* current version of SysEnvirons */
- #define postponeCalc true /* postpone CalcVisBehind call */
- #define normalCalc false /* do normal CalcVisBehind call */
-
-
- /*
- * T Y P E S
- *
- * Type definitions of some structures.
- */
-
- /* The WINDData structure matches the structure of a WIND resource
- in a resource file. It is used to access the various fields of
- the WIND resource after it has been read in from the file. */
-
- struct WINDRecord
- {
- Rect boundsRect;
- INTEGER procID;
- Boolean visible;
- char filler1;
- Boolean goAwayFlag;
- char filler2;
- LONGINT refCon;
- Str255 title;
- };
- typedef struct WINDRecord WINDData;
- typedef struct WINDRecord *WINDPtr;
- typedef struct WINDRecord **WINDHandle;
-
- /* The WDEFHeader structure matches the structure of the (optional)
- header of a window definition procedure resource. */
-
- struct WDEFRecord
- {
- INTEGER branch;
- INTEGER flags;
- LONGINT type;
- INTEGER ID;
- INTEGER version;
- };
- typedef struct WDEFRecord WDEFHeader;
- typedef struct WDEFRecord *WDEFPtr;
- typedef struct WDEFRecord **WDEFHandle;
-
-
- /*
- * G L O B A L S
- *
- * The TWindow Manager's globals. ToBeActivated and toBeDeactivated hold
- * the next window to be activated and deactivated respectively. FrontTool-
- * Window, backToolWindow and frontDocWindow are pointers to the frontmost
- * visible tool window, the backmost visible tool window, and the frontmost
- * visible document window. FirstRgn and secondRgn are region handles that
- * are used in several places in the TWindow Manager,but are allocated only
- * once for efficiency. TheWorld is a standard SysEnvirons data structure
- * that describes the capabilities of the system we are running on.
- */
-
- static WindowPeek toBeActivated,
- toBeDeactivated,
- frontToolWindow,
- backToolWindow,
- frontDocWindow;
- static RgnHandle firstRgn,
- secondRgn;
- static SysEnvRec theWorld;
-
-
- /*
- * T I N I T W I N D O W S
- *
- * TInitWindows must be called before any other TWindow Manager functions
- * are called. It is used to initialize the global variables.
- *
- * Note that TInitWindows is no replacement for InitWindows. It does _not_
- * call InitWindows; that is up to the calling application.
- *
- * Parameters:
- *
- * <none>
- *
- * Local variables and used functions:
- *
- * OSErr err; result of SysEnvirons call
- *
- * Global variables and constants:
- *
- * WindowPeek frontToolWindow, frontmost tool window
- * backToolWindow, backmost tool window
- * frontDocWindow, frontmost document window
- * toBeActivated, window that needs activating
- * toBeDeactivated; window that needs deactivating
- * RgnHandle firstRgn, region used for various purposes
- * secondRgn; region used for various purposes
- */
-
- void
- TInitWindows()
- {
- OSErr err;
-
- frontToolWindow =
- backToolWindow =
- frontDocWindow =
- toBeDeactivated =
- toBeActivated = nil;
- firstRgn = NewRgn();
- secondRgn = NewRgn();
- err = SysEnvirons( curVersion, &theWorld );
- }
-
-
- /*
- * T G E T N E W W I N D O W
- *
- * TGetNewWindow is a special version of the GetNewWindow call for creating
- * tool windows and documents windows, as specified by a window template in
- * a resource file. If the window template could not be read in from the
- * resource file, or the window definition function for this window could
- * not be read into memory, nil is returned. The window's windowKind field
- * is set to the value of the windowKind parameter. If you want this window
- * to behave as a tool window, pass the constant toolKind as windowKind.
- *
- * TGetNewWindow first calls GetResource to get the window template into
- * memory. In then calls NewWindow to create the window, invisible. If the
- * caller specified a visible window ( by setting the visible field in the
- * template to true), the function TShowWindow is called to make it visible
- * and to update any global variables,post activate events and to make sure
- * the window appears in its proper plane.
- *
- * Parameters:
- *
- * IN:
- *
- * INTEGER windowKind; type of window to create;
- *
- * The rest of TGetNewWindow's parameters are the same as the
- * parameters for the standard toolbox function GetNewWindow.
- *
- * OUT:
- *
- * WindowPtr TGetNewWindow(); the new window
- *
- * Local variables and used functions:
- *
- * Rect boundsRect; NewWindow parameter
- * Str255 title; NewWindow parameter
- * Boolean visible; NewWindow parameter
- * INTEGER procID; NewWindow parameter
- * Boolean goAwayFlag; NewWindow parameter
- * LONGINT refCon; NewWindow parameter
- * WindowPtr theWindow, the new window
- * WINDHandle theWINDHandle; handle to window template
- * WINDPtr theWINDPtr; pointer to window template
- *
- * Constants:
- *
- * Boolean invisible; false, so window is invisible
- */
-
- WindowPtr
- TGetNewWindow( windowKind, windowID, wStorage, behind )
- INTEGER windowKind;
- INTEGER windowID;
- Ptr wStorage;
- WindowPtr behind;
- {
- Rect boundsRect;
- Str255 title;
- Boolean visible;
- INTEGER procID;
- Boolean goAwayFlag;
- LONGINT refCon;
- WindowPtr theWindow;
- WINDHandle theWINDHandle;
- WINDPtr theWINDPtr;
-
- /* Read the window template in from the resource file. */
-
- theWINDHandle = ( WINDHandle )GetResource( 'WIND', windowID );
- if ( theWINDHandle != nil )
- {
- /* Copy the window template values to variables in
- preparation of a NewWindow call. */
-
- theWINDPtr = *theWINDHandle;
- boundsRect = theWINDPtr->boundsRect;
- visible = theWINDPtr->visible;
- procID = theWINDPtr->procID;
- goAwayFlag = theWINDPtr->goAwayFlag;
- refCon = theWINDPtr->refCon;
- if ( theWINDPtr->title.length == 0 )
- title.length = 0;
- else
- BlockMove( &( theWINDPtr->title ), &title,
- ( Size )theWINDPtr->title.length + 1 );
- p2cstr( &title );
-
- /* Release the used resource. Create the window, but
- make it invisible. */
-
- ReleaseResource(( Handle )theWINDHandle );
- theWindow = NewWindow( wStorage, &boundsRect, &title, invisible,
- procID, behind, goAwayFlag, refCon );
- if ( theWindow != nil )
- {
- /* Set the windowKind field. If the window is a tool,
- make sure it is highlighted. If the user originally
- specified a visible window in the window template,
- show it now. */
-
- (( WindowPeek )theWindow )->windowKind = windowKind;
- if ( visible != false )
- TShowWindow( theWindow );
- }
- }
- else
- theWindow = nil;
- return( theWindow );
- }
-
- /* End of TGetNewWindow */
-
-
- /*
- * T N E W W I N D O W
- *
- * TNewWindow is a special version of the NewWindow call for creating tool
- * windows and documents windows. If the window definition function for
- * this window could not be read into memory, nil is returned. The window's
- * windowKind field is set to the value of the windowKind parameter. If you
- * want this window to behave as a tool window, pass the constant toolKind
- * as windowKind.
- *
- * TNewWindow calls NewWindow to create the window, invisible. If a visible
- * window was specified by the caller, the function TShowWindow is called
- * to make it visible and to update any global variables, post activate
- * events and to make sure the window appears only in the plane it should
- * be in.
- *
- * Parameters:
- *
- * IN:
- *
- * INTEGER windowKind; type of window to create
- *
- * The rest of TNewWindow's parameters are the same as the
- * parameters for the standard toolbox function NewWindow.
- *
- * OUT:
- *
- * WindowPtr TNewWindow(); the new window
- *
- * Local variables and used functions:
- *
- * WindowPtr theWindow; the new window
- *
- * Constants:
- *
- * Boolean invisible; false, so window is invisible
- */
-
- WindowPtr
- TNewWindow( windowKind, wStorage, boundsRect, title,
- visible, procID, behind, goAwayFlag, refCon )
- INTEGER windowKind;
- Ptr wStorage;
- Rect *boundsRect;
- char *title;
- Boolean visible;
- INTEGER procID;
- WindowPtr behind;
- Boolean goAwayFlag;
- LONGINT refCon;
- {
- WindowPtr theWindow;
-
- /* Create the window, invisible. */
-
- theWindow = NewWindow( wStorage, boundsRect, title, invisible,
- procID, behind, goAwayFlag, refCon );
- if ( theWindow != nil )
- {
- /* Set the windowKind field. If the window is a tool,
- make sure it is highlighted. If the user specified
- a visible window, show it now. */
-
- (( WindowPeek )theWindow )->windowKind = windowKind;
- if ( visible != false )
- TShowWindow( theWindow );
- }
- return( theWindow );
- }
-
- /* End of TNewWindow */
-
-
- /*
- * T C L O S E W I N D O W
- *
- * TCloseWindow is a replacement for the standard CloseWindow function
- * in the toolbox. It calls THideWindow first, to make the window in-
- * visible. Then it calls CloseWindow to close the window. Finally it
- * checks if there is a pending deactivate event for the window. If
- * there is, it removes the deactivate event, since it is no longer
- * necessary.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPtr theWindow; window to be closed
- *
- * Global variables:
- *
- * WindowPtr toBeDeactivated; window that needs deactivating
- */
-
- void
- TCloseWindow( theWindow )
- WindowPtr theWindow;
- {
- THideWindow( theWindow );
- CloseWindow( theWindow );
-
- if ( theWindow == toBeDeactivated )
- toBeDeactivated = nil;
- }
-
- /* End of TCloseWindow */
-
-
- /*
- * T D I S P O S E W I N D O W
- *
- * TDisposeWindow is a replacement for the standard DisposeWindow trap
- * in the toolbox. It calls THideWindow first, to make the window in-
- * visible. Then it calls DisposeWindow to dispose of the windowrecord.
- * Finally it checks if there is a pending deactivate event for the
- * window. If there is, it removes the deactivate event, since it is
- * no longer necessary.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPtr theWindow; window to be disposed of
- *
- * Global variables:
- *
- * WindowPtr toBeDeactivated; window that needs deactivating
- */
-
- void
- TDisposeWindow( theWindow )
- WindowPtr theWindow;
- {
- THideWindow( theWindow );
- DisposeWindow( theWindow );
-
- if ( theWindow == toBeDeactivated )
- toBeDeactivated = nil;
- }
-
- /* End of TDisposeWindow */
-
-
- /*
- * T S E L E C T W I N D O W
- *
- * TSelectWindow is a replacement for the Toolbox routine SelectWindow.
- * It moves the selected document window to the front, just behind the
- * the backmost tool window, highlights it, and marks it for activation
- * for the next TGetNextEvent call. The current frontmost window is un-
- * highlighted, and is marked for deactivation. Tool windows can also
- * be selected when the user clicks them: they are moved completely to
- * the front, just like SelectWindow does.
- *
- * If a desk accessory is in front when a window is selected, all the
- * tool windows and the frontmost document window will be moved on top
- * of the desk accessory.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPtr theWindow; window to be selected
- *
- * Local variables and used functions:
- *
- * void BringForward(); brings a window forward behind
- * another
- * WindowPeek thePWindow, WindowPeek version of the window
- * theFrontWindow, frontmost window
- * NextVisWindow(), next visible window in the list
- * PrevVisWindow(); previous visible window in the list
- * INTEGER theWKind, windowKind of the theWindow
- * frontWKind; windowKind of the theFrontWindow
- * Boolean toolsVisible, true if tool windows are visible
- * BringToolsForward();brings all tool windows in front,
- * when there's a DA on top
- *
- * Global variables:
- *
- * WindowPeek frontToolWindow, frontmost tool window
- * backToolWindow, backmost tool window
- * frontDocWindow, frontmost document window
- * toBeActivated, window that needs activating
- * toBeDeactivated; window that needs deactivating
- *
- * Constants:
- *
- * INTEGER systemKind, windowKind value for DAs
- * toolKind; windowKind value for tool windows
- */
-
- void
- TSelectWindow( theWindow )
- WindowPtr theWindow;
- {
- void BringForward();
- WindowPeek thePWindow,
- theFrontWindow,
- NextVisWindow(),
- PrevVisWindow();
- INTEGER theWKind,
- frontWKind;
- Boolean toolsVisible,
- BringToolsForward();
-
- /* Initialize some variables. */
-
- thePWindow = ( WindowPeek )theWindow;
- theFrontWindow = ( WindowPeek )FrontWindow();
- theWKind = TGetWKind( theWindow );
- frontWKind = TGetWKind(( WindowPtr )theFrontWindow );
-
- if ( theWKind == toolKind )
- {
- if ( frontWKind == systemKind )
- {
- /* Window is a tool window, with a desk accessory
- on top. Select the tool (to unhighlight the
- DA). Use BringToolsForward to move the rest of
- the tools. Move a possible document window to
- the front with BringForward. Update globals. */
-
- SelectWindow( theWindow );
- (void)BringToolsForward( thePWindow );
- if ( frontDocWindow != nil )
- {
- frontDocWindow->hilited = true;
- BringForward( frontDocWindow, backToolWindow,
- normalCalc );
- toBeActivated = frontDocWindow;
- }
- frontToolWindow = thePWindow;
- }
- else
- {
- /* Window is a tool window, and no desk accessory
- on top. Find the new backToolWindow if that is
- necessary, then bring our window to the front.
- Update our globals. */
-
- if ( thePWindow != frontToolWindow )
- {
- if ( thePWindow == backToolWindow )
- {
- backToolWindow = NextVisWindow( toolKind, thePWindow );
- if ( backToolWindow == nil )
- backToolWindow = PrevVisWindow( thePWindow );
- }
- BringToFront( theWindow );
- frontToolWindow = thePWindow;
- }
- }
- }
- else if ( theWKind == userKind )
- {
- if ( frontWKind == systemKind )
- {
- /* Window is a document window (or a modeless dialog
- window), with a desk accessory on top. Use Bring-
- ToolsForward to move the tools to the front. This
- unhighlights the desk accessory. Finish by moving
- the document window to the front (using SelectWindow
- if there were no tools to unhighlight the DA). */
-
- toolsVisible = BringToolsForward(( WindowPeek )inFront );
- if ( toolsVisible == false )
- SelectWindow( theWindow );
- else
- {
- thePWindow->hilited = true;
- BringForward( theWindow, backToolWindow, normalCalc );
- }
- toBeActivated =
- frontDocWindow = thePWindow;
- }
- else
- {
- /* Window is a document window (or a modeless dialog
- window), and no desk accessory on top. If it isn't
- already the frontmost window, use SelectWindow to
- bring it to the front if there are no tool windows
- visible, otherwise use BringForward to move the
- document window just behind the backToolWindow. */
-
- if ( thePWindow != frontDocWindow )
- {
- if ( frontToolWindow == nil )
- SelectWindow( theWindow );
- else
- {
- HiliteWindow(( WindowPtr )frontDocWindow, false );
- thePWindow->hilited = true;
- BringForward( thePWindow, backToolWindow,
- normalCalc );
- }
- toBeDeactivated = frontDocWindow;
- toBeActivated =
- frontDocWindow = thePWindow;
- }
- }
- }
- }
-
- /* End of TSelectWindow */
-
-
- /*
- * T H I D E W I N D O W
- *
- * THideWindow is a replacement for the toolbox routine HideWindow. It
- * is used to make a window invisible ( it has no effect if the window
- * is already invisible). If the window is the frontmost document win-
- * dow and there is a document window behind it, THideWindow will high-
- * light that window and post an activate event for it. If the window
- * behind it is a desk accessory and there are still tool windows in
- * front, the desk accessory will be brought in front of the tools.
- *
- * THideWindow uses GetWPosition to find out the exact position of the
- * window with respect to other windows on the desktop. It then takes
- * specific action for each type of position, such as moving windows to
- * an allowed location first, or highlighting windows manually, posting
- * activate events and updating the global variables frontToolWindow,
- * backToolWindow and frontDocWindow.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPtr theWindow; window to be hidden
- *
- * Local variables and used functions:
- *
- * WindowPeek thePWindow, WindowPeek version of theWindow
- * behindWindow; window behind theWindow when
- * theWindow is behindTools
- * INTEGER theWKind, the window's windowKind
- * thePosition, the window's relative position
- * GetWPosition(); determines window's position
- * void HiliteTools(); (Un)highlights all the tools
- *
- * Global variables:
- *
- * WindowPeek frontToolWindow, frontmost tool window
- * backToolWindow, backmost tool window
- * frontDocWindow, frontmost document window
- * toBeActivated, window that needs activating
- * toBeDeactivated; window that needs deactivating
- *
- * Constants:
- *
- * INTEGER systemKind, windowKind for DA windows
- * toolKind, windowKind for tool windows
- * alone, no other windows visible
- * beforeDialog, it is before the frontmost window,
- * which is a dialog window
- * beforeSystem, it is before the frontmost window,
- * which is a system window
- * beforeTool, it is before the frontmost window,
- * which is a tool window
- * beforeDocument, it is before the frontmost window,
- * which is a document window
- * behindFrontSystem, it is behind the frontmost window,
- * which is a system window
- * betweenTools, it is among the tool windows
- * behindTools, it is behind all the tool windows
- * but before any document windows
- * behindSystem, it is behind all the tool windows
- * and behind a system window
- * betweenDocuments; it is behind the first document
- * window
- */
-
- void
- THideWindow( theWindow )
- WindowPtr theWindow;
- {
- WindowPeek thePWindow,
- behindWindow;
- INTEGER theWKind,
- thePosition,
- frontWKind,
- GetWPosition();
- void HiliteTools();
-
- if ((( WindowPeek )theWindow )->visible != false )
- {
- /* Save some window values, for later unhighlighting
- and deactivating. */
-
- thePWindow = ( WindowPeek )theWindow;
- theWKind = TGetWKind( theWindow );
- thePosition = GetWPosition( thePWindow, &frontWKind );
-
- /* Hide the window, and update the desktop
- according to the window's position. */
-
- if ( theWKind == toolKind )
- {
- /* The window is a tool window. */
-
- switch( thePosition )
- {
- case alone:
- case beforeSystem:
- HideWindow( theWindow );
- frontToolWindow =
- backToolWindow = nil;
- break;
-
- case beforeTool:
- ShowHide( theWindow, false );
- frontToolWindow = ( WindowPeek )FrontWindow();
- break;
-
- case behindFrontSystem:
- ShowHide( theWindow, false );
- frontToolWindow =
- NextVisWindow( toolKind, thePWindow );
- if ( frontToolWindow == nil )
- backToolWindow = nil;
- break;
-
- case beforeDocument:
- frontToolWindow =
- backToolWindow = nil;
- ShowHide( theWindow, false );
- break;
-
- /* NOTE: no behindTools possible! */
-
- case betweenTools:
- ShowHide( theWindow, false );
- if ( thePWindow == backToolWindow )
- backToolWindow = PrevVisWindow( thePWindow );
- break;
- }
- }
- else if ( theWKind == userKind )
- {
- /* The window is a document window
- (or a modeless dialog window). */
-
- thePWindow->hilited = false;
-
- switch( thePosition )
- {
- case alone:
- case beforeSystem:
- toBeDeactivated = thePWindow;
- frontDocWindow = nil;
-
- case betweenDocuments:
- HideWindow( theWindow );
- break;
-
- case beforeDocument:
- HideWindow( theWindow );
- toBeDeactivated = thePWindow;
- toBeActivated =
- frontDocWindow = ( WindowPeek )FrontWindow();
- break;
-
- case behindFrontSystem:
- ShowHide( theWindow, false );
- frontDocWindow =
- NextVisWindow( userKind, theWindow );
- break;
-
- case behindTools:
- frontDocWindow =
- NextVisWindow( userKind, theWindow );
- behindWindow =
- NextVisWindow( anyKind, theWindow );
- ShowHide( theWindow, false );
- if ( behindWindow == nil )
- toBeDeactivated = thePWindow;
- else
- {
- if ( behindWindow != frontDocWindow )
- {
- if ( frontWKind == toolKind )
- {
- HiliteTools( false );
- SelectWindow(( WindowPtr )behindWindow );
- toBeDeactivated = thePWindow;
- }
- if ( frontDocWindow != nil )
- BringForward( frontDocWindow,
- backToolWindow, normalCalc );
- }
- else
- {
- if ( frontWKind == toolKind )
- {
- HiliteWindow( frontDocWindow, true );
- toBeActivated = frontDocWindow;
- toBeDeactivated = thePWindow;
- }
- }
- }
- break;
- }
- }
- else
- {
- /* The window is a modal dialog window. */
-
- switch( thePosition )
- {
- case alone:
- case beforeSystem:
- case beforeDialog:
- HideWindow( theWindow );
- break;
-
- case beforeTool:
- case beforeDocument:
- ShowHide( theWindow, false );
- HiliteTools( true );
- if ( frontDocWindow != nil )
- {
- toBeDeactivated = thePWindow;
- toBeActivated = frontDocWindow;
- HiliteWindow(( WindowPtr )frontDocWindow, true );
- }
- break;
- }
- }
- }
- }
-
- /* End of THideWindow */
-
-
- /*
- * T S H O W W I N D O W
- *
- * TShowWindow is a replacement for the standard ShowWindow function in
- * the toolbox. Like ShowWindow, TShowWindow makes the window visible
- * if it's not already visible (otherwise it has no effect). It also
- * makes very sure that the window will appear in an allowed position
- * for that window after it's been made visible.
- *
- * TShowWindow calls GetWPosition to find out the exact position of the
- * window with respect to other windows on the desktop. It then takes
- * specific action for each type of position, such as moving windows to
- * an allowed location first, or highlighting windows manually, posting
- * activate events and updating the global variables front- and back-
- * ToolWindow and frontDocWindow.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPtr theWindow; window to be shown
- *
- * Local variables:
- *
- * WindowPeek thePWindow, WindowPeek version of theWindow
- * theFrontWindow; frontmost visible window
- * INTEGER theWKind, theWindow's windowKind
- * frontWKind, windowKind of theFrontWindow
- * thePosition, the window's relative position
- * GetWPosition(); determines window's position
- * Boolean toolsExist; true if tools are visible
- *
- * Used functions:
- *
- * WindowPeek PrevVisWindow(); window in front of given window
- * Boolean BringToolsForward();brings all tools forward
- * void BringForward(), brings a window forward behind
- * another
- * HiliteTools(); (Un)highlights all the tools
- *
- * Global variables:
- *
- * WindowPeek frontToolWindow, frontmost tool window
- * backToolWindow, backmost tool window
- * frontDocWindow, frontmost document window
- * toBeActivated, window that needs activating
- * toBeDeactivated; window that needs deactivating
- *
- * Constants:
- *
- * INTEGER systemKind, windowKind for DA windows
- * toolKind, windowKind for tool windows
- * alone, no other windows visible
- * beforeDialog, it is before the frontmost window,
- * which is a dialog window
- * beforeSystem, it is before the frontmost window,
- * which is a system window
- * beforeTool, it is before the frontmost window,
- * which is a tool window
- * beforeDocument, it is before the frontmost window,
- * which is a document window
- * behindFrontSystem, it is behind the frontmost window,
- * which is a system window
- * betweenTools, it is among the tool windows
- * behindTools, it is behind all the tool windows
- * but before any document windows
- * behindSystem, it is behind all the tool windows
- * and behind a system window
- * betweenDocuments; it is behind the first document
- * window
- */
-
- void
- TShowWindow( theWindow )
- WindowPtr theWindow;
- {
- WindowPeek thePWindow,
- theFrontWindow,
- behind,
- PrevVisWindow();
- INTEGER theWKind,
- frontWKind,
- thePosition,
- GetWPosition();
- Boolean toolsExist,
- BringToolsForward();
- void BringForward(),
- HiliteTools();
-
- if ((( WindowPeek )theWindow )->visible == false )
- {
- /* The window is still invisible. */
-
- thePWindow = ( WindowPeek )theWindow;
- theFrontWindow = ( WindowPeek )FrontWindow();
- theWKind = TGetWKind( theWindow );
- thePosition = GetWPosition( thePWindow, &frontWKind );
-
- if ( theWKind == toolKind )
- {
- /* The window is a tool window. Assume it needs
- to appear highlighted (correct this later). */
-
- thePWindow->hilited = true;
-
- switch( thePosition )
- {
- case beforeSystem:
- ShowWindow( theWindow );
- ( void )BringToolsForward( thePWindow );
- if ( frontDocWindow != nil )
- {
- frontDocWindow->hilited = true;
- BringForward( frontDocWindow,
- backToolWindow, normalCalc );
- toBeActivated = frontDocWindow;
- }
- frontToolWindow = thePWindow;
- break;
-
- case behindFrontSystem:
- thePWindow->hilited = false;
-
- case alone:
- case beforeDocument:
- if ( backToolWindow == nil )
- backToolWindow = thePWindow;
-
- case beforeTool:
- ShowHide( theWindow, true );
- frontToolWindow = thePWindow;
- break;
-
- case behindTools:
- backToolWindow = thePWindow;
-
- case betweenTools:
- if ( frontWKind == systemKind )
- thePWindow->hilited = false;
- ShowHide( theWindow, true );
- break;
-
- case behindSystem:
- SendBehind( theWindow,
- ( WindowPtr )backToolWindow );
- if ( frontWKind == systemKind )
- thePWindow->hilited = true;
- ShowHide( theWindow, true );
- backToolWindow = thePWindow;
- break;
-
- case betweenDocuments:
- if ( backToolWindow != nil )
- behind = backToolWindow;
- else
- {
- behind = PrevVisWindow( frontDocWindow );
- frontToolWindow = thePWindow;
- }
- if ( behind == nil )
- BringToFront( theWindow );
- else
- {
- SendBehind( theWindow, behind );
- if ( frontWKind == systemKind )
- thePWindow->hilited = false;
- }
- ShowHide( theWindow, true );
- backToolWindow = thePWindow;
- break;
- }
- }
- else if ( theWKind == userKind )
- {
- /* The window is a document window. */
-
- switch( thePosition )
- {
- case beforeSystem:
- toolsExist = BringToolsForward(
- ( WindowPeek )inFront );
- if ( toolsExist != false )
- thePWindow->hilited = true;
-
- case alone:
- ShowWindow( theWindow );
- toBeActivated =
- frontDocWindow = thePWindow;
- break;
-
- case beforeTool:
- if ( frontDocWindow != nil )
- {
- HiliteWindow(( WindowPtr )frontDocWindow,
- false );
- toBeDeactivated = frontDocWindow;
- }
- SendBehind( theWindow, backToolWindow );
- thePWindow->hilited = true;
- ShowHide( theWindow, true );
- toBeActivated =
- frontDocWindow = thePWindow;
- break;
-
- case beforeDocument:
-
- /* The three steps HiliteWindow,
- HiliteWindow and ShowHide could be
- replaced with one call to ShowWindow,
- but this gives a better visual effect.
- (Try the difference.) */
-
- HiliteWindow( frontDocWindow, false );
- HiliteWindow( theWindow, true );
- ShowHide( theWindow, true );
- toBeDeactivated = frontDocWindow;
- toBeActivated =
- frontDocWindow = thePWindow;
- break;
-
- case behindFrontSystem:
- if ( backToolWindow != nil )
- SendBehind( theWindow,
- ( WindowPtr )backToolWindow );
- ShowHide( theWindow, true );
- frontDocWindow = thePWindow;
- break;
-
- case betweenTools:
- SendBehind( theWindow,
- ( WindowPtr )backToolWindow );
-
- case behindTools:
- if ( frontWKind == toolKind )
- {
- thePWindow->hilited = true;
- toBeActivated = thePWindow;
- if ( frontDocWindow != nil )
- {
- HiliteWindow(( WindowPtr )frontDocWindow,
- false );
- toBeDeactivated = frontDocWindow;
- }
- }
- ShowHide( theWindow, true );
- frontDocWindow = thePWindow;
- break;
-
- case behindSystem:
- SendBehind( theWindow,
- ( WindowPtr )backToolWindow );
- if ( frontWKind == toolKind )
- {
- thePWindow->hilited = true;
- toBeActivated = thePWindow;
- }
- ShowHide( theWindow, true );
- frontDocWindow = thePWindow;
- break;
-
- case betweenDocuments:
- ShowHide( theWindow, true );
- break;
- }
- }
- else
- {
- /* The window is a modal dialog window. */
-
- switch( thePosition )
- {
- case alone:
- case beforeSystem:
- case beforeDialog:
- ShowWindow( theWindow );
- break;
-
- case beforeTool:
- case beforeDocument:
- HiliteTools( false );
- if ( frontDocWindow != nil )
- {
- toBeDeactivated = frontDocWindow;
- HiliteWindow(( WindowPtr )frontDocWindow, false );
- }
- ShowHide( theWindow, true );
- break;
- }
- }
- }
- }
-
- /* End of TShowWindow */
-
-
- /*
- * T F R O N T W I N D O W
- *
- * TFrontWindow effectively replaces the Toolbox trap FrontWindow in an
- * environment with tool windows. This function is not only for deter-
- * mining just the frontmost visible window, but the caller can also
- * specify what kind of window it wants in the wantedKind parameter.
- * If there is a desk accessory or modal dialog on top, TFrontWindow
- * will return a pointer to the desk accessory's or dialog's window.
- *
- * Parameters:
- *
- * IN:
- *
- * INTEGER wantedKind; kind of window to look for
- *
- * OUT:
- *
- * WindowPtr TFrontWindow(); frontmost document window or nil
- *
- * Local variables and used functions:
- *
- * WindowPtr theWindow; the frontmost window
- * INTEGER theWKind; the front window's windowKind
- *
- * Global variables and constants:
- *
- * WindowPeek frontDocWindow, frontmost document window
- * frontToolWindow; frontmost tool window
- * INTEGER systemKind, windowKind value for DA windows
- * toolKind, windowKind value for tool windows
- * anyKind; windowKind "wildcard"
- */
-
- WindowPtr
- TFrontWindow( wantedKind )
- INTEGER wantedKind;
- {
- WindowPtr theWindow;
- INTEGER theWKind;
-
- theWindow = FrontWindow();
- theWKind = TGetWKind( theWindow );
-
- if ( theWKind == systemKind ||
- theWKind == dialogKind )
- return( theWindow );
- else
- switch ( wantedKind )
- {
- case toolKind:
- return(( WindowPtr )frontToolWindow );
- break;
-
- case userKind:
- return(( WindowPtr )frontDocWindow );
- break;
-
- case anyKind:
- return( theWindow );
- break;
- }
- }
-
- /* End of TFrontWindow */
-
-
- /*
- * T D R A G W I N D O W
- *
- * TDragWindow is the replacement for the Toolbox routine DragWindow.
- * There are three things that DrawWindow does which are replaced in
- * TDragWindow: if the window is not in front it needs to be brought to
- * the front (if the command key is not being held down). This is done
- * with a call to TSelectWindow.
- *
- * The second thing is the dragging itself. We use DragGrayRgn to draw
- * a gray outline of the window (its strucRgn) around, _below_ any tool
- * windows and other document windows that may be lying on top of it.
- * This is accomplished by setting the clipRgn of the Window Manager
- * port (the port we're drawing in) "to be the desktop intersected with
- * the current clipRgn, minus the structure regions of all the windows
- * in front of the given window". This is exactly what the low-level
- * QuickDraw routine ClipAbove does.
- *
- * The third and last step is to examine the result of DragGrayRgn, and
- * to move the window accordingly. Watch the frequent changing of coor-
- * dinates from global to local and vice versa!
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPtr theWindow; pointer to the window to be dragged
- * EventRecord *theEvent; pointer to event that caused this
- * call to TDragWindow
- *
- * Local variables and used functions:
- *
- * GrafPtr savePort, for saving the current grafport
- * wPort; for holding the Window Manager port
- * Rect limitRect, parameter for DragGrayRgn
- * slopRect; parameter for DragGrayRgn
- * RgnHandle desktopRgn; region for holding the desktop region
- * LONGINT result; value DragGrayRgn returns
- * INTEGER hDrag, horizontal displacement after dragging
- * vDrag; vertical displacement after dragging
- * Point thePoint; for calculating new position
- *
- * Global constants and variables:
- *
- * WindowPeek frontDocWindow, frontmost document window
- * RgnHandle GrayRgn, low memory global holding desktop region
- * firstRgn, for saving the Window Manager's clipRgn
- * secondRgn; region that holds the drag outline
- */
-
- void
- TDragWindow( theWindow, theEvent, boundsRect )
- WindowPtr theWindow;
- EventRecord *theEvent;
- Rect *boundsRect;
- {
- GrafPtr savePort,
- wPort;
- Rect limitRect,
- slopRect;
- RgnHandle desktopRgn;
- LONGINT result;
- INTEGER hDrag,
- vDrag;
- Point thePoint;
-
- if (( theEvent->modifiers & cmdKey ) == false )
- {
- /* If the command key is not being held down, call
- TSelectWindow to bring the window to the front.
- (TSelectWindow will determine if this is really
- necessary.) Then make sure the mouse is still
- down before we start dragging. */
-
- TSelectWindow( theWindow );
- if ( StillDown() == false )
- return;
- }
- /* Save the current port and set it to the Window
- Manager port, since we're going to draw the
- drag outline in this port. */
-
- GetPort ( &savePort );
- GetWMgrPort( &wPort );
- SetPort ( wPort );
-
- /* Get a handle to the current desktop region.
- There is a routine for this on newer machines,
- but the old 64K ROM Mac and Mac XL will still
- have to get it from the low memory global GrayRgn. */
-
- /* if ( theWorld.machineType == envMac ||
- theWorld.machineType == envXL ) */
- desktopRgn = GrayRgn;
- /* else
- desktopRgn = GetGrayRgn(); */
-
- /* Set the clipping region to the current desktop
- region, intersected with all the windows above
- theWindow. */
-
- GetClip ( firstRgn );
- SetClip ( desktopRgn );
- ClipAbove(( WindowPeek )theWindow );
-
- /* Finally call DragGrayRgn to drag the outline
- of the window. */
-
- CopyRgn((( WindowPeek )theWindow )->strucRgn, secondRgn );
- SetPt ( &thePoint, theEvent->where.h, theEvent->where.v );
- GlobalToLocal( &thePoint );
- result = DragGrayRgn( secondRgn, &thePoint, boundsRect,
- boundsRect, noConstraint, ( ProcPtr )nil );
-
- /* Restore the Window Manager port's clipRgn. */
-
- SetClip( firstRgn );
-
- /* Check if the user actually moved the window.
- If so, call MoveWindow to move the window to
- its new location. */
-
- vDrag = HiWord( result );
- hDrag = LoWord( result );
- if ( !( vDrag == noDrag && hDrag == noDrag ))
- {
- SetPort( theWindow );
- SetPt ( &thePoint, theWindow->portRect.left,
- theWindow->portRect.top );
- LocalToGlobal( &thePoint );
- MoveWindow( theWindow, thePoint.h + hDrag,
- thePoint.v + vDrag, false );
- }
-
- /* Restore the original grafport, and clear out
- the region handles. */
-
- SetPort( savePort );
- SetEmptyRgn( firstRgn );
- SetEmptyRgn( secondRgn );
- }
-
- /* End of TDragWindow */
-
-
- /*
- * T G E T N E X T E V E N T
- *
- * TGetNextEvent is a replacement for the Toolbox routine GetNextEvent.
- * It still calls GetNextEvent, but filters the activate events and
- * sometimes inserts activate events of its own. This is because the
- * movement of document windows behind the tool windows goes unnoticed
- * by the Window Manager, and no activate events are posted for them.
- *
- * If there is a true activate event in the queue, it is because either
- * a window was moved completely to the front, or a desk accessory was
- * opened or closed. In the latter case, the frontmost window get the
- * event, but it is really meant for the frontmost document window,
- * which may be lying behind some tool windows. TGetNextEvent modifies
- * the event record to reflect this.
- *
- * When the event queue doesn't hold any events of its own, we check
- * our own two globals toBeDeactivated and toBeActivated,in that order.
- * If one of them points to a window, we return an activate event for
- * that window.
- *
- * Finally, if there are no activate events in the queue,but some other
- * types, or if the event queue is empty, we simply call GetNextEvent
- * and return the result.
- *
- * Parameters:
- *
- * IN:
- *
- * INTEGER eventMask; types of events we want
- *
- * OUT:
- *
- * EventRecord *theEvent; event is returned here
- *
- * Local variables and used functions:
- *
- * Boolean result, result of GetNextEvent call
- * WindowExists(); true if passed window exists
- * INTEGER theWKind; window's windowKind
- * void HiliteTools(); (Un)highlights all the tools
- *
- * Global constants and variables:
- *
- * WindowPeek toBeActivated, window that needs activating
- * toBeDeactivated, window that needs deactivating
- * frontDocWindow; frontmost document window
- * INTEGER deactivFlag; modifiers for a deactivate event
- */
-
- Boolean
- TGetNextEvent( eventMask, theEvent )
- INTEGER eventMask;
- EventRecord *theEvent;
- {
- Boolean result,
- WindowExists();
- INTEGER theWKind;
- void HiliteTools();
-
- if ( EventAvail( eventMask, theEvent ) != false &&
- theEvent->what == activateEvt )
- {
- /* If there is an official activate event in the queue, get
- it with GetNextEvent, and see what caused it. If the
- corresponding toBe... flag is the same as the activated
- or deactivated window, it was a window that was brought
- to the front with SelectWindow or (Get)NewWindow.
-
- In that case the toBe... flag will already have been set
- up correctly, so don't do anything. If the (de)activated
- window is not equal to the right toBe... flag, it means
- a desk accessory was opened or closed. In that case,
- pass the event on to the frontmost document window. */
-
- result = GetNextEvent( eventMask, theEvent );
- theWKind = TGetWKind(( WindowPtr )theEvent->message );
-
- if (( theEvent->modifiers & activeFlag ) == false )
- {
- if ( theEvent->message != ( LONGINT )toBeDeactivated )
- {
- if ( toBeDeactivated != nil )
- theEvent->message = ( LONGINT )toBeDeactivated;
- else
- {
- if ( theWKind == userKind ||
- theWKind == toolKind )
- {
- if ( theWKind == toolKind )
- HiliteTools( false );
- if ( frontDocWindow != nil )
- {
- HiliteWindow(( WindowPtr )frontDocWindow, false );
- theEvent->message = ( LONGINT )frontDocWindow;
- }
- else
- result = TGetNextEvent( eventMask, theEvent );
- }
- }
- }
- toBeDeactivated = nil;
- }
- else
- {
- if ( theEvent->message != ( LONGINT )toBeActivated )
- {
- if ( toBeActivated != nil )
- theEvent->message = ( LONGINT )toBeActivated;
- else
- {
- if ( theWKind == userKind ||
- theWKind == toolKind )
- {
- if ( theWKind == toolKind )
- HiliteTools( true );
- if ( frontDocWindow != nil )
- {
- HiliteWindow(( WindowPtr )frontDocWindow, true );
- theEvent->message = ( LONGINT )frontDocWindow;
- }
- else
- result = TGetNextEvent( eventMask, theEvent );
- }
- }
- }
- toBeActivated = nil;
- }
- }
- else
- {
- /* If there is no official activate event, but another type
- of event, or perhaps no event at all, first check to see
- if one of our toBe... variables is set, meaning that one
- of our windows needs activating or deactivating. If so,
- fill in the caller's event record with the information
- for the (de)activate event. If none of our windows needs
- activating or deactivating, just call GetNextEvent to
- get a pending event or a null event for the caller. */
-
- if ( toBeDeactivated != nil &&
- ( eventMask & activMask ) != false )
- {
- if ( WindowExists( toBeDeactivated ) != false )
- {
- /* IMPORTANT: check if the window we are about to
- deactivate still exists. This won't be a problem
- if the window was removed by the TCloseWindow or
- TDisposeWindow function (since these functions
- remove the deactivate event themselves). It is
- necessary if the window belonged to a dialog box
- and was removed by CloseDialog or DisposDialog.
- Of course they don't clear toBeDeactivated... */
-
- theEvent->what = activateEvt;
- theEvent->message = ( LONGINT )toBeDeactivated;
- theEvent->modifiers = deactivFlag;
- toBeDeactivated = nil;
- result = true;
- }
- else
- {
- /* The deactivate event was no longer valid,so call
- TGetNextEvent again to get a fresh event. And
- clear the bogus event of course. */
-
- toBeDeactivated = nil;
- result = TGetNextEvent( eventMask, theEvent );
- }
- }
- else if ( toBeActivated != nil &&
- ( eventMask & activMask ) != false )
- {
- theEvent->what = activateEvt;
- theEvent->message = ( LONGINT )toBeActivated;
- theEvent->modifiers = activeFlag;
- toBeActivated = nil;
- result = true;
- }
- else
- {
- result = GetNextEvent( eventMask, theEvent );
- }
- }
- /* Return the result value to indicate if we have an event. */
-
- return( result );
- }
-
- /* End of TGetNextEvent */
-
-
- /*
- * W I N D O W E X I S T S
- *
- * WindowExists determines if the given window is an existing window.
- * It traverses the window list and if the window is not found, returns
- * false. If the window is found, it returns true.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPeek thePWindow; window to check for existance
- *
- * OUT:
- *
- * Boolean WindowExists(); true if window exists
- *
- * Local variables and used functions:
- *
- * WindowPeek loopWindow, to traverse the window list
- * Boolean done; true if window exists
- */
-
- Boolean
- WindowExists( thePWindow )
- WindowPeek thePWindow;
- {
- WindowPeek loopWindow;
- Boolean done;
-
- for ( done = false,
- loopWindow = WindowList;
- done == false && loopWindow != nil;
- loopWindow = loopWindow->nextWindow )
- {
- if ( loopWindow == thePWindow )
- done = true;
- }
- return( done );
- }
-
- /* End of WindowExists */
-
-
- /*
- * G E T W P O S I T I O N
- *
- * GetWPosition is a utility function to determine the exact position
- * of a window with respect to the other windows in the window list. It
- * returns a predefined constant describing this position, and another
- * constant describing the type of window that is currently frontmost.
- *
- * GetWPosition starts at the beginning of the window list, and traver-
- * ses it until it finds our window. In the meantime, it remembers in
- * what state it is, so that when it finds the window, it knows what
- * kind of result code to return. There are 10 result codes, correspon-
- * ding to the 10 different kinds of positions a window can have.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPeek thePWindow; window to find position of
- *
- * OUT:
- *
- * INTEGER *frontWKind; kind of window currently in front
- *
- * IN/OUT:
- *
- * <none>
- *
- * Local variables and used functions:
- *
- * WindowPeek theFrontWindow, the frontmost window
- * newFrontWindow, new front window after hide
- * loopWindow, to traverse the window list
- * NextVisWindow(); returns next visible window
- * Boolean done; signals end of while loop
- * INTEGER result, result code describing position
- * loopKind; kind of window during loop
- *
- * Global variables:
- *
- * WindowPeek frontToolWindow, frontmost tool window
- * backToolWindow, backmost tool window
- * frontDocWindow; frontmost document window
- *
- * Constants:
- *
- * INTEGER systemKind, windowKind for DA windows
- * toolKind, windowKind for tool windows
- * anyKind, windowKind "wildcard"
- * alone, no other windows visible
- * beforeDialog, it is before the frontmost window,
- * which is a dialog window
- * beforeSystem, it is before the frontmost window,
- * which is a system window
- * beforeTool, it is before the frontmost window,
- * which is a tool window
- * beforeDocument, it is before the frontmost window,
- * which is a document window
- * behindFrontSystem, it is behind the frontmost window,
- * which is a system window
- * betweenTools, it is among the tool windows
- * behindTools, it is behind all the tool windows
- * behindSystem, it is behind all the tool windows,
- * and behind a system window, but
- * before any document windows
- * betweenDocuments; it is behind the first document
- * window
- */
-
- static INTEGER
- GetWPosition( thePWindow, frontWKind )
- WindowPeek thePWindow;
- INTEGER *frontWKind;
- {
- WindowPeek theFrontWindow,
- newFrontWindow,
- loopWindow,
- NextVisWindow();
- Boolean done;
- INTEGER result,
- loopWKind;
-
- /* Initialize several variables. */
-
- theFrontWindow = ( WindowPeek )FrontWindow();
-
- /* If our window is visible and the frontmost,
- examine the visible window behind ours. */
-
- if ( thePWindow->visible != false &&
- theFrontWindow == thePWindow )
- newFrontWindow = NextVisWindow( anyKind, theFrontWindow );
- else
- newFrontWindow = theFrontWindow;
-
- /* If our window is visible, and there are no
- windows following it, or if our window is
- invisible and there are no visible windows
- at all, return right away. */
-
- if ( newFrontWindow == nil )
- return( alone );
- *frontWKind = TGetWKind(( WindowPtr )newFrontWindow );
-
- if ( thePWindow->visible != false &&
- theFrontWindow == thePWindow ||
- theFrontWindow == NextVisWindow( anyKind, thePWindow ))
- {
- /* Our window is visible and the frontmost,
- or it's invisible and lying in front of
- the frontmost visible window. */
-
- if ( *frontWKind == systemKind )
- result = beforeSystem;
- else if ( *frontWKind == dialogKind )
- result = beforeDialog;
- else if ( *frontWKind == toolKind )
- result = beforeTool;
- else
- result = beforeDocument;
- }
- else
- {
- /* Our window is not completely in front, but
- behind the frontmost visible window. Traverse
- the window list, marking every transition to
- another category of windows by setting the
- result code to the current state. If our
- window is invisible, we stop when we find it.
- If our window is visible, we stop when we
- reach the window in front of it. */
-
- if (thePWindow->visible != false )
- thePWindow = PrevVisWindow( thePWindow );
-
- for ( done = false,
- loopWindow = theFrontWindow;
- done == false;
- loopWindow = loopWindow->nextWindow )
- {
- loopWKind = TGetWKind(( WindowPtr )loopWindow );
- if ( loopWindow == theFrontWindow &&
- loopWKind == systemKind )
- result = behindFrontSystem;
- else if ( loopWindow == frontToolWindow &&
- backToolWindow != frontToolWindow )
- result = betweenTools;
- else if ( loopWindow == backToolWindow )
- result = behindTools;
- else if ( loopWKind == systemKind &&
- loopWindow->visible != false &&
- result == behindTools )
- result = behindSystem;
- else if ( loopWindow == frontDocWindow )
- result = betweenDocuments;
-
- if ( loopWindow == thePWindow )
- done = true;
- }
- /* Finish by returning the result code. */
-
- return( result );
- }
- }
-
- /* End of GetWPosition */
-
-
- /*
- * T G E T W K I N D
- *
- * TGetWKind is a utility function that returns the class of the window
- * that is passed to it, based on the WindowRecord's windowKind field.
- * TGetWKind returns the constant systemKind if the window is a desk
- * accessory, the constant dialogKind if it's a modal dialog or alert
- * window, the constant toolKind if it's a tool window, and finally the
- * constant userKind for a document window or a modeless dialog window.
- *
- * TGetWKind simply returns the value of windowKind in most cases (when
- * the window is a DA, it always chooses systemKind, and when it is a
- * standard window it always chooses userKind, no matter what the real
- * value of windowKind may be). It also returns userKind for a modeless
- * dialog window.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPtr theWindow; window to find position of
- *
- * OUT:
- *
- * <none>
- *
- * IN/OUT:
- *
- * <none>
- *
- * Local variables:
- *
- * INTEGER theWKind, windowKind of theWindow
- * windowID; windowID of theWindow
- * Handle defProc; handle to theWindow's defProc
- *
- * Global variables:
- *
- * SysEnvRec theWorld; SysEnvirons record
- *
- * Constants:
- *
- * INTEGER systemKind, windowKind for DA windows
- * toolKind; windowKind for tool windows
- */
-
- INTEGER
- TGetWKind( theWindow )
- WindowPtr theWindow;
- {
- INTEGER theWKind,
- varCode,
- windowID;
- WDEFHandle defProc;
-
- if ( theWindow != nil )
- {
- theWKind = (( WindowPeek )theWindow )->windowKind;
-
- if ( theWKind <= systemKind )
- theWKind = systemKind;
- else if ( theWKind == dialogKind )
- {
- defProc =
- ( WDEFHandle )(( WindowPeek )theWindow )->windowDefProc;
-
- /* if ( theWorld.machineType == envMac ||
- theWorld.machineType == envXL ) */
- varCode = ( LONGINT )defProc >> 24 && 0x0000000F;
- /* else
- varCode = GetWVariant( theWindow ); */
-
- if ( defProc != nil &&
- *defProc != nil &&
- ( *defProc )->type == 'WDEF' )
- windowID = ( *defProc )->ID * 16 + varCode;
- else
- windowID = dBoxProc;
-
- if ( windowID == documentProc ||
- windowID == noGrowDocProc ||
- windowID == zoomDocProc )
- theWKind = userKind;
- }
- else if ( theWKind == toolKind )
- /* nothing */ ;
- else if ( theWKind >= userKind )
- theWKind = userKind;
- }
- return( theWKind );
- }
-
- /* End of TGetWKind */
-
-
- /*
- * B R I N G T O O L S F O R W A R D
- *
- * BringToolsForward is used to move a range of visible tool windows further
- * to the front. If the behindWindow parameter is inFront, BringToolsForward
- * will use SelectWindow to bring the first visible tool window to the front,
- * effectively deactivating a desk accessory that may be lying on top. It
- * will then traverse the rest of the visible tool windows and bring them
- * all behind that first selected one. If the behindWindow parameter is not
- * equal to inFront, BringToolsForward will just traverse the visible tool
- * windows following behindWindow and move them forward to the new position
- * (just behind behindWindow), "across" any desk accessories. Note that the
- * BringForward function is passed the postponeCalc parameter. This tells it
- * not to call the time-consuming CalcVisBehind function during each move.
- * Instead, BringToolsForward saves up all the regions for one call to Calc-
- * VisBehind, after all the tools are moved forward.
- *
- * BringToolsForward returns true if it really encountered visible tool win-
- * dows and moved them forward. If there were no tool visible windows at
- * all, a result of false is returned.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPeek thePWindow; move visible tool windows forward
- * just behind this window, or to the
- * front if it's equal to inFront
- * OUT:
- *
- * Boolean BringToolsForward();true if tools were brought forward
- * and the desk accessory deactivated
- *
- * Local variables and used functions:
- *
- * WindowPeek NextVisWindow(); returns next visible window
- * toolWindow, used for various purposes
- * loopWindow; used for various purposes
- * void BringForward(); moves a window behind another
- *
- * Global variables and constants:
- *
- * INTEGER toolKind; windowKind value for tool windows
- * WindowPtr inFront; indicates we want window in front
- * WindowPeek toBeActivated, window that needs activating
- * frontToolWindow, frontmost tool window
- * backToolWindow; backmost tool window
- * RgnHandle secondRgn; clobberedRgn for CalcVisBehind
- * Boolean postponeCalc; tells BringForward not to call
- * CalcVisBehind yet
- */
-
- static Boolean
- BringToolsForward( thePWindow )
- WindowPeek thePWindow;
- {
- WindowPeek NextVisWindow(),
- toolWindow,
- loopWindow;
- void BringForward();
-
- if ( thePWindow == ( WindowPeek )inFront )
- {
- /* Find the frontmost tool window behind the DA(s). */
-
- toolWindow = NextVisWindow( toolKind, ( WindowPeek )FrontWindow() );
-
- /* If it's not nil, we use SelectWindow to bring it in
- front (and to deactivate the desk accessory). Back-
- ToolWindow and frontToolWindow are initialized, and
- loopWindow is prepared for traversing the remaining
- visible tool windows. */
-
- if ( toolWindow != nil )
- {
- loopWindow = toolWindow->nextWindow;
- SelectWindow(( WindowPtr )toolWindow );
- frontToolWindow =
- backToolWindow = toolWindow;
- }
- /* If it's nil, it means there are no visible tool
- windows. Return with false to indicate that there
- are no tool windows visible and that the topmost DA
- has not been deactivated yet. */
- else
- {
- return( false );
- }
- }
- /* Set up loopWindow and backToolWindow to start moving
- the visible tool windows behind thePWindow forward. */
- else
- {
- loopWindow = thePWindow->nextWindow;
- backToolWindow = thePWindow;
- }
-
- /* Traverse the rest of the visible tool windows,
- and move them just behind backToolWindow, across
- the DA(s). Add each tool window's strucRgn to
- the region that will be used for one call to
- CalcVisBehind. */
-
- SetEmptyRgn( secondRgn );
- thePWindow = nil;
-
- while ( loopWindow != nil )
- {
- if ( loopWindow->windowKind == toolKind &&
- loopWindow->visible != false )
- {
- toolWindow = loopWindow;
- toolWindow->hilited = true;
- BringForward( toolWindow, backToolWindow, postponeCalc );
- UnionRgn( secondRgn, toolWindow->strucRgn, secondRgn );
- backToolWindow = toolWindow;
- if ( thePWindow == nil )
- thePWindow = toolWindow;
- }
- loopWindow = loopWindow->nextWindow;
- }
-
- CalcVisBehind( thePWindow, secondRgn );
- SetEmptyRgn( secondRgn );
-
- /* Return true to indicate that there are actually
- tool windows visible (and that all of those
- visible windows were moved). */
-
- return( true );
- }
-
- /* End of BringToolsForward */
-
-
- /*
- * N E X T V I S W I N D O W
- *
- * NextVisWindow returns the next visible window of type wantedKind following
- * thePWindow. It traverses the window list, skipping invisible windows and
- * windows of the wrong type, until it finds this type of window. If it does
- * not find a next visible window, nil is returned.
- *
- * It is allowed to pass the constant inFront as thePWindow; searching will
- * then commence with the frontmost visible window. If wantedKind is equal
- * to the predefined constant anyKind, NextVisWindow returns the next visible
- * window, no matter what kind.
- *
- * Parameters:
- *
- * IN:
- *
- * INTEGER wantedKind; kind of window to look for
- * WindowPeek thePWindow; window to start looking behind
- *
- * OUT:
- *
- * WindowPeek NextVisWindow(); first visible wantedKind window
- * behind thePWindow or nil
- *
- * Local variables and used functions:
- *
- * WindowPeek loopWindow, used for various purposes
- * wantedWindow; window to look for; end of for loop
- *
- * Constants:
- *
- * INTEGER anyKind; windowKind "wildcard"
- * WindowPtr inFront; indicates we want window in front
- */
-
- static WindowPeek
- NextVisWindow( wantedKind, thePWindow )
- INTEGER wantedKind;
- WindowPeek thePWindow;
- {
- WindowPeek loopWindow,
- wantedWindow;
-
- /* If thePWindow is equal to the predefined constant
- inFront, set it to FrontWindow(). Check if this is
- possibly the window we're looking for. If yes, return
- it. If no, fall through to the loop below. */
-
- if ( thePWindow == ( WindowPeek )inFront )
- {
- thePWindow = ( WindowPeek )FrontWindow();
- if ( thePWindow == nil )
- return( thePWindow );
- else if ( wantedKind == anyKind ||
- wantedKind == TGetWKind(( WindowPtr )thePWindow ))
- return( thePWindow );
- }
-
- /* Traverse the window list, starting with the window
- following thePWindow, in search of the frontmost
- visible wantedKind type window. */
-
- for ( wantedWindow = nil,
- loopWindow = thePWindow->nextWindow;
- wantedWindow == nil &&
- loopWindow != nil;
- loopWindow = loopWindow->nextWindow )
- {
- if ( loopWindow->visible != false )
- if ( wantedKind == anyKind ||
- wantedKind == TGetWKind(( WindowPtr )loopWindow ))
- wantedWindow = loopWindow;
- }
-
- return( wantedWindow );
- }
-
- /* End of NextVisWindow */
-
-
- /*
- * P R E V V I S W I N D O W
- *
- * PrevVisWindow returns the next visible window in front of thePWindow in
- * the window list. It traverses the window list until it finds this window.
- * If there is no such window, PrevVisWindow returns nil.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPeek thePWindow; window to find previous visible for
- *
- * OUT:
- *
- * WindowPeek PrevVisWindow(); first visible window in front of
- * thePWindow, or nil if none
- *
- * Local variables and used functions:
- *
- * WindowPeek loopWindow, used for various purposes
- * prevWindow, candidate for previous visible window
- * theFrontWindow, frontmost visible window
- * NextVisWindow(); next visible window in window list
- * Boolean done; signals end of while loop
- *
- * Constants:
- *
- * INTEGER anyKind; windowKind "wildcard"
- */
-
- static WindowPeek
- PrevVisWindow( thePWindow )
- WindowPeek thePWindow;
- {
- WindowPeek loopWindow,
- prevWindow,
- theFrontWindow,
- NextVisWindow();
- Boolean done;
-
- theFrontWindow = ( WindowPeek )FrontWindow();
-
- /* If thePWindow is the frontmost visible or even
- frontmost invisible window, return nil. */
-
- if ( thePWindow == theFrontWindow ||
- theFrontWindow == NextVisWindow( anyKind, thePWindow ))
- return(( WindowPeek )nil );
-
- /* Traverse the window list, starting with the
- frontmost visible window, and see if one of
- the windows following it up to (and including)
- the next visible window is our window. If not,
- move to the next visible window. */
-
- prevWindow = theFrontWindow;
- loopWindow = prevWindow->nextWindow;
- done = false;
-
- while ( done == false )
- {
- if ( loopWindow == thePWindow )
- done = true;
- else
- if ( loopWindow->visible != false )
- prevWindow = loopWindow;
- loopWindow = loopWindow->nextWindow;
- }
-
- return( prevWindow );
- }
-
- /* End of PrevVisWindow */
-
-
- /*
- * B R I N G F O R W A R D
- *
- * BringForward is a special function to move a window further to the front.
- * The move is accomplished by three calls to the Window Manager: SendBehind
- * to move the window, PaintOne to paint the newly uncovered content region,
- * and finally - if waitWithCalc is not true - CalcVisBehind to recalculate
- * the visRgns of all the windows behind our window. NOTE: Inside Macintosh
- * (page I-286) mentions that a call to SendBehind in a case like this must
- * be followed by calls to the routines PaintOne and CalcVis. However, Calc-
- * Vis just isn't enough here: we need to recalculate the visRgns of _all_
- * windows behind our window.
- *
- * Parameters:
- *
- * IN:
- *
- * WindowPeek thePWindow, window that needs to be moved forward
- * behindWindow; ... behind this window
- * Boolean waitWithCalc; if true, dont call CalcVisBehind
- *
- * Global variables:
- *
- * RgnHandle firstRgn; uncovered region of window to redraw
- */
-
- static void
- BringForward( thePWindow, behindWindow, waitWithCalc )
- WindowPeek thePWindow;
- WindowPeek behindWindow;
- Boolean waitWithCalc;
- {
- /* The newly exposed part of the structure region of our window
- is calculated (remember that visRgn is in local coordinates). */
-
- CopyRgn ( thePWindow->strucRgn, firstRgn );
- OffsetRgn( thePWindow->port.visRgn,
- - thePWindow->port.portBits.bounds.left,
- - thePWindow->port.portBits.bounds.top );
- DiffRgn ( firstRgn, thePWindow->port.visRgn, firstRgn );
- OffsetRgn( thePWindow->port.visRgn,
- thePWindow->port.portBits.bounds.left,
- thePWindow->port.portBits.bounds.top );
-
- /* Move the window to its new position, paint the newly
- exposed part of of the window's contents white, and
- recalculate the lower windows' visRgns. */
-
- SendBehind(( WindowPtr )thePWindow, ( WindowPtr )behindWindow );
- PaintOne ( thePWindow, firstRgn );
- if ( waitWithCalc == false )
- CalcVisBehind( thePWindow, thePWindow->strucRgn );
- SetEmptyRgn( firstRgn );
- }
-
- /* End of BringForward */
-
-
- /*
- * H I L I T E T O O L S
- *
- * HiliteTools is a utility function that highlights or unhighlights all the
- * tool windows that are visible. Its main purpose is to unhighlight the
- * tools whenever a window that doesn't belong to the application is brought
- * to the front,or to highlight the tools when such a window is removed from
- * the frontmost position. This can be a desk accessory when running the
- * standard Mac operating system, or can be any application's window when
- * running under MultiFinder.
- *
- * Parameters:
- *
- * IN:
- *
- * Boolean hilite; true = hilite, false = unhilite
- *
- * Local variables and used functions:
- *
- * WindowPeek loopWindow; used to traverse windows
- * Boolean done; signals end of while loop
- *
- * Global variables:
- *
- * WindowPeek frontToolWindow, frontmost tool window
- * backToolWindow; backmost tool window
- */
-
- static void
- HiliteTools( hilite )
- Boolean hilite;
- {
- WindowPeek loopWindow;
- Boolean done;
-
- if ( frontToolWindow != nil )
- {
- for ( done = false,
- loopWindow = frontToolWindow;
- done == false && loopWindow != nil;
- loopWindow = loopWindow->nextWindow )
- {
- if ( TGetWKind(( WindowPtr )loopWindow ) == toolKind &&
- loopWindow->visible != false )
- {
- HiliteWindow(( WindowPtr )loopWindow, hilite );
- if ( loopWindow == backToolWindow )
- done = true;
- }
- }
- }
- }
-
- /* End of HiliteTools */
-